package com.adobe.training.core;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
public class BreakingInheritancePageCopyListener implements EventListener {

    private final Logger LOGGER = LoggerFactory.getLogger(BreakingInheritancePageCopyListener.class);

    @Reference
    private SlingRepository repository;

    private Session session;
    private ObservationManager observationManager;

    protected void activate(ComponentContext context) throws Exception {
        session = repository.loginAdministrative(null);
        observationManager = session.getWorkspace().getObservationManager();
        observationManager.addEventListener(this, Event.NODE_ADDED, "/content/", true, null, null, true);
        LOGGER.info("********added JCR event listener");
    }

    protected void deactivate(ComponentContext componentContext) throws RepositoryException {
        try {
            if (observationManager != null) {
                observationManager.removeEventListener(this);
                LOGGER.info("********removed JCR event listener");
            }
        }
        finally {
            if (session != null) {
                session.logout();
                session = null;
            }
        }
    }

    public void onEvent(EventIterator events) { 
        while (events.hasNext()) {
            Event event = events.nextEvent();
            try {             
                LOGGER.info("********Page Copy Listener Event: {}", event.getPath());                
                if(!event.getPath().contains("jcr:content")){
                    Node node = session.getNode(event.getPath());
                    if(node.getProperty("jcr:primaryType").getString().equals("cq:Page")){
                        Node node2 = getNodeCopiedFrom(node);
                        if(node2 != null){                            
                            try{
                                session.getNode(node.getPath() + "/jcr:content/cq:LiveSyncConfig");
                                session.removeItem(node.getPath() + "/jcr:content/cq:LiveSyncConfig");   
                                LOGGER.info("********cq:LiveSyncConfig removed: {}", node.getPath() + "/jcr:content");
                                removeMixinLiveRelationship(node);                                
                                session.save();
                            }
                            catch(PathNotFoundException ex){
                                //do nothing
                            }
                        }
                    }
                }
            }
            catch (Exception e) { 
                LOGGER.error(e.getMessage(), e);
            }
        }
    }
    
    private void removeMixinLiveRelationship(Node node) throws RepositoryException{
        NodeType[] nt = node.getMixinNodeTypes();
        for(NodeType n : nt){
            if(n.getName().equals("cq:LiveRelationship")){
                node.removeMixin("cq:LiveRelationship");
                LOGGER.info("********cq:LiveRelationship removed: {}", node.getPath());
            }
        }
        NodeIterator ni =  node.getNodes();
        while(ni.hasNext()){
            removeMixinLiveRelationship((Node)ni.next());
        }
    }
    
    private Node getNodeCopiedFrom(Node node) throws RepositoryException {
        if(node != null){
            char a = node.getPath().charAt(node.getPath().length()-1);
            int num = Character.digit(a, 10);
            if (num >= 1 && num <= 9){
                try{
                    Node node2 = session.getNode(node.getPath().substring(0, node.getPath().length()-1));
                    if(node2 != null){ 
                        Node tmpNode1 = session.getNode(node2.getPath() + "/jcr:content");                   
                        String title1 = tmpNode1.getProperty("jcr:title").getString();
                        Node tmpNode2 = session.getNode(node.getPath() + "/jcr:content");                            
                        String title2 = tmpNode2.getProperty("jcr:title").getString();
                        if(title1.equals(title2)){
                            return node2;
                        }
                    }
                }
                catch(PathNotFoundException ex){
                    LOGGER.info("********Could not find the copied node", node.getPath().substring(0, node.getPath().length()-1));
                    //ex.printStackTrace();
                }
            }
        }
        return null;
    }
}
